<?php
/**
 * $Id: request.php 21 2009-06-10 02:24:31Z eyou80 $
 */

/**
 * 服务器请求处理类
 *
 * @package Request
 */
class Tinyask_Request
{
	/**
	 *  内部参数
	 *
	 * @var array
	 */
	private static $_params = array();

	/**
	 * 路径信息
	 *
	 * @var string
	 */
	private static $_pathInfo = null;

	/**
	 * 获取指定的参数
	 *
	 * @param string $name
	 * @param mixed $default
	 * @return mixed
	 */
	public static function getParam($name, $default = null)
	{
		switch (true) {
			case isset(self::$_params[$name]):
				$value = self::$_params[$name];
				break;
			case isset($_GET[$name]):
				$value = $_GET[$name];
				break;
			case isset($_GET[$name]):
				$value = $_POST[$name];
				break;
			case isset($_COOKIE[$name]):
				$value = $_COOKIE[$name];
				break;
			default:
				$value = $default;
		}
		return $value;
	}

	/**
	 * 设置参数的值
	 *
	 * @param string $name
	 * @param mixed $value
	 */
	public static function setParam($name, $value)
	{
		self::$_params[$name] = $value;
	}

	/**
	 * 参数是否存在
	 *
	 * @param string $name
	 * @return boolean
	 */
	public static function issetParam($name)
	{
		return isset(self::$_params[$name])
		|| isset($_GET[$name])
		|| isset($_POST[$name])
		|| isset($_COOKIE[$name]);
	}

	/**
	 * 从参数列表中获取指定的参数的值
	 *
	 * @param mixed $param
	 * @return array
	 */
	public static function getParamsFrom($param)
	{
		$params = array();

		if(is_array($param)) {
			$args = $param;
		} else {
			$args = func_get_args();

		}

		foreach($args as $arg) {
			$params[$arg] = self::getParam($arg);
		}

		return $params;
	}

	/**
	 * 获取指定的COOKIE值
	 *
	 * @param string $name
	 * @param mixed $default
	 * @return mixed
	 */
	public static function getCookie($name, $default = null)
	{
		return isset($_COOKIE[$name]) ? $_COOKIE[$name] : $default;
	}

	/**
	 * 获取指定的SESSION值
	 *
	 * @param string $name
	 * @param mixed $default
	 * @return mixed
	 */
	public static function getSession($name, $default = null)
	{
		return isset($_SESSION[$name]) ? $_SESSION[$name] : $default;
	}

	/**
	 * 请求是否为AJAX
	 *
	 * @return boolean
	 */
	public static function isAjax()
	{
		return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtoupper($_SERVER['HTTP_X_REQUESTED_WITH']) == 'XMLHTTPREQUEST';
	}

	/**
	 * 获取客户端IP
	 *
	 * @return string
	 */
	public static function getIp()
	{
		switch(true) {
			case isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown'):
				$ip = $_SERVER['REMOTE_ADDR'];
				break;
			case getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown'):
				$ip = getenv('HTTP_CLIENT_IP');
				break;
			case getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown'):
				$ip = getenv('HTTP_X_FORWARDED_FOR');
				break;
			case getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown'):
				$ip = getenv('REMOTE_ADDR');
				break;
			default:
				$ip = 'unknown';
		}

		$ips = array();
		preg_match_all("/[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}/", $ip, $ips);
		return $ips[0] . '.' . $ips[1] . '.' . $ips[2] . '.' . $ips[3];
	}

	/**
	 * 获取网页来源
	 *
	 * @return string
	 */
	public static function getReferer()
	{
		return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : getenv('HTTP_REFERER');
	}

	/**
	 * 获取客户端信息
	 *
	 * @return string
	 */
	public static function getAgent()
	{
		return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : getenv('HTTP_USER_AGENT');
	}

	/**
	 * 请求方法是否为POST
	 *
	 * @return boolean
	 */
	public static function isPost()
	{
		return ($_SERVER['REQUEST_METHOD'] == 'POST');
	}

	/**
	 * 请求方式是否为GET
	 *
	 * @return boolean
	 */
	public static function isGet()
	{
		return ($_SERVER['REQUEST_METHOD'] == 'GET');
	}

	/**
	 * 请求方式是否为PUB
	 *
	 * @return boolean
	 */
	public static function isPut()
	{
		return ($_SERVER['REQUEST_METHOD'] == 'PUT');
	}

	/**
	 * 获取当前pathinfo
	 *
	 * @return string
	 */
	public static function getPathInfo()
	{
		if(self::$_pathInfo !== null) {
			return self::$_pathInfo;
		}

		$pathInfo = null;

		$requestUri = null;

		if(isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch
			$requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
		} elseif (isset($_SERVER['REQUEST_URI'])) {
			$requestUri = $_SERVER['REQUEST_URI'];
			if(isset($_SERVER['HTTP_HOST']) && strpos($requestUri, $_SERVER['HTTP_HOST']) !== false) {
				$parts = @parse_url($requestUri);
				if($parts !== false) {
					$requestUri = (empty($parts['path']) ? '' : $parts['path']) . (empty($parts['query']) ? '' : '?' . $parts['query']);
				}
			}
		} elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI
			$requestUri = $_SERVER['ORIG_PATH_INFO'];
			if(!empty($_SERVER['QUERY_STRING'])) {
				$requestUri .= '?' . $_SERVER['QUERY_STRING'];
			}
		} else {
			return self::$_pathInfo = '/';
		}

		//处理baseUrl
		$fileName = isset($_SERVER['SCRIPT_FILENAME']) ? basename($_SERVER['SCRIPT_FILENAME']) : '';

		if(isset($_SERVER['SCRIPT_NAME']) && basename($_SERVER['SCRIPT_NAME']) === $fileName) {
			$baseUrl = $_SERVER['SCRIPT_NAME'];
		} elseif (isset($_SERVER['PHP_SELF']) && basename($_SERVER['PHP_SELF']) === $fileName) {
			$baseUrl = $_SERVER['PHP_SELF'];
		} elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $fileName) { // 1and1 shared hosting compatibility
			$baseUrl = $_SERVER['ORIG_SCRIPT_NAME'];
		}  else {
			// Backtrack up the script_filename to find the portion matching
			// php_self
			$path = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
			$file = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
			$segs = explode('/', trim($file, '/'));
			$segs = array_reverse($segs);
			$index = 0;
			$last = count($segs);
			$baseUrl = '';
			do {
				$seg = $segs[$index];
				$baseUrl = '/' . $seg . $baseUrl;
				++$index;
			} while ($last > $index && ($pos = strpos($path, $baseUrl)) !== false && $pos != 0);
		}

		// Does the baseUrl have anything in common with the request_uri?
		$finalBaseUrl = null;

		if(strpos($requestUri, $baseUrl) === 0) {
			// full $baseUrl matches
			$finalBaseUrl = $baseUrl;
		} elseif (strpos($requestUri, dirname($baseUrl)) === 0) {
			// directory portion of $baseUrl matches
			$finalBaseUrl = rtrim(dirname($baseUrl), '/');
		}  elseif (strpos($requestUri, basename($baseUrl)) === false) {
			$finalBaseUrl = '';
		}  elseif (strlen($requestUri) >= strlen($baseUrl) && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) {
			// If using mod_rewrite or ISAPI_Rewrite strip the script filename
			// out of baseUrl. $pos !== 0 makes sure it is not matching a value
			// from PATH_INFO or QUERY_STRING
			$baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
		}

		$finalBaseUrl = (null === $finalBaseUrl) ? rtrim($baseUrl, '/') : $finalBaseUrl;

		// Remove the query string from REQUEST_URI
		if($pos = strpos($requestUri, '?')) {
			$requestUri = substr($requestUri, 0, $pos);
		}

		if($finalBaseUrl !== null && (false === ($pathInfo = substr($requestUri, strlen($finalBaseUrl))))) {
			// If substr() returns false then PATH_INFO is set to an empty string
			$pathInfo = '/';
		}  elseif ($finalBaseUrl === null) {
			$pathInfo = $requestUri;
		}

		return (self::$_pathInfo = urldecode(empty($pathInfo) ? '/' : $pathInfo));
	}
}
